<template>
	<div class="pt-4 px-[25px] md:px-[35px] pb-10">
		<template v-if="walletStore.loading.fiatWithdrawChannel">
			<BaseLoadingCircle class="mt-20 mb-[225px] mx-auto" />
		</template>
		<template v-else-if="!walletStore.fiatWithdrawChannel?.length">
			<BaseEmpty class="my-20" />
		</template>
		<form v-else @submit.prevent="onEnter">
			<input type="submit" class="hidden" />
			<WalletSelectCurrency
				type="fiat"
				:options="walletStore.fiatWithdrawChannel"
				v-model:currency="selectedCurrency"
				v-model:currency-item="selectedCurrencyItem" />
			<template v-if="selectedCurrencyItem?.bankFlag === 1">
				<BaseInput
					labelT="wallet.cardholderName"
					v-model="formValue.bankAccountName"
					:errorT="formRule.bankAccountName.result.textT"
					:is-danger="!formRule.bankAccountName.result.valid"
					@blur="formRule.bankAccountName.validator()"
					@focus="formReset('bankAccountName')" />
				<BaseSelect
					class="mb-4"
					labelT="wallet.bank"
					v-model="formValue.bank"
					v-model:item="selectedBankItem"
					:options="
						selectedCurrencyItem.bankList.map((i: any) => ({
							...i,
							iconImg: i.appIcon,
							text: i.bankName
						}))
					" />
				<BaseInput
					labelT="wallet.bankBranch"
					v-model="formValue.bankBranch"
					:errorT="formRule.bankBranch.result.textT"
					:is-danger="!formRule.bankBranch.result.valid"
					@blur="formRule.bankBranch.validator()"
					@focus="formReset('bankBranch')" />
				<BaseInput
					labelT="wallet.bankcardNo"
					v-model="formValue.bankCardNo"
					type="number"
					:errorT="formRule.bankCardNo.result.textT"
					:is-danger="!formRule.bankCardNo.result.valid"
					@blur="formRule.bankCardNo.validator()"
					@focus="formReset('bankCardNo')" />
			</template>
			<template v-if="selectedCurrencyItem?.bankFlag === 2">
				<BaseInput
					labelT="wallet.walletAddress"
					v-model="formValue.address"
					:errorT="formRule.address.result.textT"
					:is-danger="!formRule.address.result.valid"
					@blur="formRule.address.validator()"
					@focus="formReset('address')" />
			</template>
			<BaseInput
				labelT="withdraw.amount"
				v-model="formValue.amount"
				type="number"
				class="!mb-1"
				:errorT="formRule.amount.result.textT"
				:is-danger="!formRule.amount.result.valid"
				@blur="formRule.amount.validator()"
				@focus="formReset('amount')">
				<template #title>
					<div class="flex items-center">
						<span>{{ $t('withdraw.amount') }}</span>
						<base-amount
							class="ml-auto text-t-3 text-sm"
							:value="formValue.amount"
							:currency="selectedCurrencyItem?.currency"
							hide-currency
							reverse-fiat />
					</div>
				</template>
				<template #suffix>
					<BaseCurrency
						class="ml-1"
						:currency="
							walletStore.walletConfig.displayCryptoInFiat
								? walletStore.walletConfig.selectedFiatCurrency
								: selectedCurrency
						" />
					<div
						class="flex items-center h-10 ml-1 -mr-2 px-[10px] rounded-xl bg-bg-3 app-bg-react"
						:class="{ '!cursor-not-allowed': !selectedCurrencyItem }"
						@click="handleMax">
						{{ $t('wallet.max') }}
					</div>
				</template>
			</BaseInput>
			<BaseTip>
				<span>{{ $t('wallet.minWithdrawAmount') }}:&nbsp;</span>
				<BaseAmount v-if="feeItem" :value="feeItem.minAmount" :currency="feeItem.assetId" />
			</BaseTip>
			<BaseTip>
				<span>{{ $t('wallet.maxWithdrawAmount') }}:&nbsp;</span>
				<BaseAmount v-if="feeItem" :value="feeItem.maxAmount" :currency="feeItem.assetId" />
			</BaseTip>
			<BaseTip>
				<span>{{ $t('wallet.withdrawFeeFiat') }}</span>
				<span>&nbsp;(&nbsp;{{ percentage(feeItem?.percent) }}&nbsp;+&nbsp;</span>
				<BaseAmount v-if="feeItem" :value="feeItem.fixed" :currency="feeItem.assetId" />
				<span>&nbsp;)&nbsp;:&nbsp;</span>
				<BaseAmount
					v-if="totalFees"
					:value="totalFees.amount"
					:currency="totalFees.currency"
					:currencyTo="totalFees.currencyTo" />
			</BaseTip>
			<BaseButton
				class="mt-[25px]"
				type="primary"
				textT="wallet.withdraw"
				:loading="loading"
				@click="onEnter" />
		</form>
	</div>
	<AccountOperateVerify ref="operateVerifyRef" @close="loading = false" @finish="onSubmit" />
</template>

<script setup lang="ts">
import { computed, nextTick, onMounted, reactive, ref, watch } from 'vue'
import { find } from 'lodash-es'
import { submitFiatWithdraw } from '@/api/wallet.ts'
import { CurrencyEnum } from '@/enums'
import { AccountOperateVerify } from '@/components/account'
import {
	BaseAmount,
	BaseButton,
	BaseCurrency,
	BaseEmpty,
	BaseInput,
	BaseLoadingCircle,
	BaseSelect,
	BaseTip
} from '@/components/base'
import { WalletSelectCurrency } from '@/components/wallet'
import { useWalletStore } from '@/store'
import { showSuccess, useRequest } from '@/hooks'
import {
	calcAmount,
	calcExchangeRate,
	Decimals,
	fmtBalanceDecimal,
	isLength,
	isWalletAddress,
	percentage,
	t
} from '@/utils'
import { Action, FaitWithdrawFee } from '@/types'
import { RuleType } from '@/components/base/input-rule/index.vue'

defineOptions({ name: 'ViewsWalletWithdrawFiat' })

const walletStore = useWalletStore()
const operateVerifyRef = ref<InstanceType<typeof AccountOperateVerify>>()
const selectedCurrency = ref<CurrencyEnum | ''>('')
const selectedCurrencyItem = ref<any>()
const selectedBankItem = ref<any>()
const formValue = reactive({
	bankAccountName: '',
	bank: '',
	bankBranch: '',
	bankCardNo: '',
	address: '',
	amount: ''
})
const formRule = reactive({
	bankAccountName: {
		hasInput: false,
		result: <RuleType>{ valid: true },
		validator: (action?: Action) => {
			if (action === Action.reset) return (formRule.bankAccountName.result = { valid: true })
			if (action === Action.input) formRule.bankAccountName.hasInput = true
			if (action === Action.blur && !formRule.bankAccountName.hasInput) return
			const value = formValue.bankAccountName
			let msg = ''
			if (selectedCurrencyItem.value?.bankFlag === 1) {
				if (!value) {
					msg = 'tip.input.required'
				} else if (!isLength(value, 2, 32)) {
					msg = 'error.invalidFormat'
				}
			}
			formRule.bankAccountName.result = { textT: msg, valid: !msg }
		}
	},
	// bank: {
	// 	hasInput: false,
	// 	result: <RuleType>{ valid: true },
	// 	validator: (action?: Action) => {
	// 		if (action === Action.reset) return (formRule.bank.result = { valid: true })
	// 		if (action === Action.input) formRule.bank.hasInput = true
	// 		if (action === Action.blur && !formRule.bank.hasInput) return
	// 		const value = formValue.bank
	// 		let msg = ''
	// 		if (selectedCurrencyItem.value?.bankFlag === 1) {
	// 			if (!value) {
	// 				msg = 'tip.input.required'
	// 			} else if (!isLength(value, 2, 32)) {
	// 				msg = 'error.invalidFormat'
	// 			}
	// 		}
	// 		formRule.bank.result = { textT: msg, valid: !msg }
	// 	}
	// },
	bankBranch: {
		hasInput: false,
		result: <RuleType>{ valid: true },
		validator: (action?: Action) => {
			if (action === Action.reset) return (formRule.bankBranch.result = { valid: true })
			if (action === Action.input) formRule.bankBranch.hasInput = true
			if (action === Action.blur && !formRule.bankBranch.hasInput) return
			const value = formValue.bankBranch
			let msg = ''
			if (selectedCurrencyItem.value?.bankFlag === 1) {
				if (!value) {
					msg = 'tip.input.required'
				} else if (!isLength(value, 2, 32)) {
					msg = 'error.invalidFormat'
				}
			}
			formRule.bankBranch.result = { textT: msg, valid: !msg }
		}
	},
	bankCardNo: {
		hasInput: false,
		result: <RuleType>{ valid: true },
		validator: (action?: Action) => {
			if (action === Action.reset) return (formRule.bankCardNo.result = { valid: true })
			if (action === Action.input) formRule.bankCardNo.hasInput = true
			if (action === Action.blur && !formRule.bankCardNo.hasInput) return
			const value = formValue.bankCardNo
			let msg = ''
			if (selectedCurrencyItem.value?.bankFlag === 1) {
				if (!value) {
					msg = 'tip.input.required'
				} else if (!/^\d{13,19}$/.test(value)) {
					msg = 'error.invalidFormat'
				}
			}
			formRule.bankCardNo.result = { textT: msg, valid: !msg }
		}
	},
	address: {
		hasInput: false,
		result: <RuleType>{ valid: true },
		validator: (action?: Action) => {
			if (action === Action.reset) return (formRule.address.result = { valid: true })
			if (action === Action.input) formRule.address.hasInput = true
			if (action === Action.blur && !formRule.address.hasInput) return
			const value = formValue.address
			let msg = ''
			if (selectedCurrencyItem.value?.bankFlag === 2) {
				if (!value) {
					msg = 'tip.input.required'
				} else if (!isWalletAddress(value)) {
					msg = 'usdtAddressAdd.addressErrorText'
				}
			}
			formRule.address.result = { textT: msg, valid: !msg }
		}
	},
	amount: {
		hasInput: false,
		result: <RuleType>{ valid: true },
		validator: (action?: Action) => {
			if (action === Action.reset) return (formRule.amount.result = { valid: true })
			if (action === Action.input) formRule.amount.hasInput = true
			if (action === Action.blur && !formRule.amount.hasInput) return
			const value = formValue.amount
			let msg = ''
			if (selectedCurrencyItem.value && feeItem.value) {
				const { currency, freeAmount } = selectedCurrencyItem.value
				const { minAmount, maxAmount, assetId } = feeItem.value
				const minWithdraw = calcAmount(minAmount, assetId, walletStore.fiatOrFalse || currency)
				const maxWithdraw = calcAmount(maxAmount, assetId, walletStore.fiatOrFalse || currency)
				const maxInput = getMaxInput()
				const toOriginal = calcExchangeRate(walletStore.fiatOrFalse || currency, currency, value)
				if (!value) {
					msg = 'tip.input.required'
				} else if (
					// 输入值转原始币种 > 原始币种余额 || 输入值 > 当前余额减去手续费后的余额
					Number(toOriginal) > Number(freeAmount) ||
					Number(value) > (maxInput?.maxBalance ?? Number(value))
				) {
					msg = 'wallet.balanceInsufficient'
				} else if (Number(value) < Math.max(0, Number(minWithdraw.amount) || NaN)) {
					msg = 'wallet.cannotMinWithdrawAmount'
				} else if (Number(value) > (Number(maxWithdraw.amount) || NaN)) {
					msg = 'wallet.cannotMaxWithdrawAmount'
				}
			}
			formRule.amount.result = { textT: msg, valid: !msg }
		}
	}
})
const loading = ref(false)
const feeItem = computed(
	() =>
		find(walletStore.fiatWithdrawFee, { assetId: selectedCurrency.value }) as
			| FaitWithdrawFee
			| undefined
)
const totalFees = computed(() => calcTotalFees(formValue.amount))

const formReset = (field: keyof typeof formRule, withValue: boolean = false) => {
	if (withValue && formValue[field]) formValue[field] = ''
	nextTick(() => {
		formRule[field]?.hasInput && (formRule[field].hasInput = false)
		formRule[field]?.validator?.(Action.reset)
	})
}

const { run } = useRequest(submitFiatWithdraw, {
	showError: true,
	onSuccess: () => {
		// walletStore.setWithdrawData({ type: 'type', id: 'type', resultId: 2, success: true })
		// walletStore.setWithdrawResultPopupShow(true)
		walletStore.setWalletWithdrawShow(false)
		showSuccess(t('withdraw.submit.success'))
	}
})

// 计算总手续费 => (提款金额 * 手续费比例) + 固定费用
const calcTotalFees = (amount: string | number) => {
	if (!selectedCurrencyItem.value || !feeItem.value) return
	const { currency } = selectedCurrencyItem.value
	const { assetId, fixed, percent } = feeItem.value
	const feeAmount = Decimals.mul(amount, Decimals.div(percent, 100))
	const fixedAmount = calcAmount(fixed, assetId, walletStore.fiatOrFalse || currency)
	return {
		amount: Decimals.add(feeAmount, fixedAmount.amount),
		currency: walletStore.fiatOrFalse || currency,
		currencyTo: currency
	}
}
// 设置最大提款金额 => 当前余额 - ((提款金额 * 手续费比例) + 固定费用) 与 最大提款金额取较小值 并且大于0; 如果接口max为0则不限制
const getMaxInput = () => {
	if (!selectedCurrencyItem.value || !feeItem.value) return
	const { currency, freeAmount } = selectedCurrencyItem.value
	const { maxAmount, assetId } = feeItem.value
	const balance = calcAmount(freeAmount, currency)
	const maxWithdraw = calcAmount(maxAmount, assetId, currency)
	const maxBalance = Decimals.sub(balance.amount, calcTotalFees(balance.amount)?.amount)
	const echo = Math.max(0, Math.min(Number(maxWithdraw.amount) || Infinity, maxBalance))
	return { amount: echo, currencyTo: balance.currencyTo, maxBalance }
}
// 设置最大提款金额 => 当前余额 - ((提款金额 * 手续费比例) + 固定费用) 与 最大提款金额取较小值 并且大于0
const handleMax = () => {
	const maxInput = getMaxInput()
	// 根据货币类型 截断取2位或8位小数
	if (maxInput) formValue.amount = fmtBalanceDecimal(maxInput?.amount, maxInput.currencyTo)
}
const submitDisabled = computed(() => {
	return (
		(selectedCurrencyItem.value?.bankFlag === 1
			? !formValue.bankAccountName ||
				!formValue.bank ||
				!formValue.bankBranch ||
				!formValue.bankCardNo
			: false) ||
		(selectedCurrencyItem.value?.bankFlag === 2 ? !formValue.address : false) ||
		!formValue.amount ||
		Object.values(formRule).some(({ result: { valid } }) => !valid)
	)
})
const onEnter = async () => {
	if (loading.value) return
	Object.values(formRule).forEach(({ validator }) => validator(Action.submit))
	await nextTick(async () => {
		if (submitDisabled.value) return
		loading.value = true
		await operateVerifyRef.value?.openVerify()
	})
}
const onSubmit = async (verify: any) => {
	if (selectedCurrencyItem.value) {
		const { currency } = selectedCurrencyItem.value
		const toOriginal = calcExchangeRate(
			walletStore.fiatOrFalse || currency,
			currency,
			formValue.amount
		)
		await run({
			currency,
			cardholderName: formValue.bankAccountName || null,
			bank: formValue.bank || null,
			// bankName: '',
			bankBranch: formValue.bankBranch || null,
			bankcardNo: formValue.bankCardNo || null,
			amount: toOriginal,
			channelId: selectedBankItem.value?.id,
			address: formValue.address || null,
			verifyType: verify?.verifyType,
			verifyCode: verify?.verifyCode
		})
		loading.value = false
	}
}

watch(selectedCurrency, () => {
	Object.values(formRule).forEach(({ validator }) => validator(Action.reset))
})

onMounted(() => {
	walletStore.getFiatWithdrawChannel()
	walletStore.getFiatWithdrawFee()
})
</script>

<style scoped></style>
